/**
 * *******************************************
 * user: zmq
 * describe: 敏感词过滤
 * created:
 * date: 2021/8/18
 * *******************************************
 */

import * as fs from "fs";
let filterObj: any = {};        // 敏感词汇对象

export default class Filter {

    /**
     * 拉取敏感词汇文本文件
     */
    private static filterLoad() {

        if (Object.keys(filterObj).length > 0) {        // 有则返回 没就拉取
            return filterObj;
        }
        let filterPath = `${__dirname}/../../config/filter/filter.txt`;
        let filterContent = fs.readFileSync(filterPath, 'utf8');
        let filterContentArr = filterContent.split('、');

        // 导入文件没有
        this.createFilter(filterContentArr);

        return filterObj;

    }

    /**
     * 导入文本文件
     * @param result
     */
    private static createFilter(result: any) {

        let self = this;
        result.forEach((value) => {
            let line = value.split('');
            let firstChar = line[0];
            let filterLeft = filterObj[firstChar];
            if (filterLeft) {
                if (filterLeft !== 1) {
                    if (line[1]) {
                        self.insertFilter(line, filterLeft, 1);
                    } else {
                        filterObj[firstChar] = 1;
                    }
                }

            } else {
                let leftChar = {}, midLeftChar = {};
                leftChar[line[line.length - 1]] = 1;
                for (let index = line.length - 2; index >= 0; index -= 1) {
                    midLeftChar[line[index]] = leftChar;
                    leftChar = midLeftChar;
                    midLeftChar = {};
                }
                filterObj[firstChar] = leftChar[firstChar];
            }
        });
    }

    /**
     * 插入文本内容
     * @param newChar
     * @param filterLeft
     * @param {number} index
     */
    private static insertFilter(newChar: any, filterLeft: any, index: number) {

        let self = this;
        let nextChar = newChar[index];
        if (nextChar) {
            let filterLeftNext = filterLeft[nextChar];
            if (filterLeftNext) {
                if (filterLeftNext !== 1) {
                    if (newChar[index + 1]) {
                        self.insertFilter(newChar, filterLeftNext, index + 1);
                    } else {
                        filterLeft[nextChar] = 1;
                    }
                }
            } else {
                let leftChar = {}, midLeftChar = {};
                leftChar[newChar[newChar.length - 1]] = 1;
                for (let key = newChar.length - 2; key >= index; key -= 1) {
                    midLeftChar[newChar[key]] = leftChar;
                    leftChar = midLeftChar;
                    midLeftChar = {};
                }
                filterLeft[nextChar] = leftChar[nextChar];
            }
        }
    }

    /**
     * 敏感词检查，对外的接口
     * @param contentMsg
     * @returns {boolean}
     */
    public static filterCheck(contentMsg: string) {

        let self = this;
        let length = contentMsg.length;
        let content = contentMsg.split('');
        let filter = self.filterLoad();

        if (!filter) {
            return true;
        }

        for (let index = 0; index < length; index += 1) {
            let char = content[index];
            if (filter[char]) {
                let result = self.filterMatch(index + 1, content, length, filter[char]);
                if (result.isSuccess === false) {
                    return false;
                }
            }
        }

        return true;
    }


    /**
     * 敏感词替换为* ，对外的接口
     * @param {string} contentMsg
     * @returns {any}
     */
    public static filterReplaceWords(contentMsg: string) {

        let self = this;
        let length = contentMsg.length;
        let content = contentMsg.split('');
        let filter = self.filterLoad();

        if (!filter) {
            return content.join('');
        }

        for (let index = 0; index < length; index += 1) {
            let char = content[index];
            if (filter[char]) {
                let result = self.filterMatch(index + 1, content, length, filter[char]);
                if (result.isSuccess === false) {
                    content.splice(index, result.endIndex - index);
                    for (let i = 0; i < result.endIndex - index; i += 1) {
                        content.splice(index, 0, '*');
                    }
                    index = result.endIndex - 1;
                }
            }
        }
        return content.join('');
    }


    /**
     * 敏感词匹配
     * @param index
     * @param content
     * @param length
     * @param matchString
     * @returns {*}
     */
    private static filterMatch(index: number, content: string[], length: number, matchString: number) {

        let self = this;
        if (matchString === 1) {
            return {isSuccess: false, endIndex: index};
        }
        if (index === length) {
            return {isSuccess: true, endIndex: index};
        }
        let char = content[index];
        if (matchString[char]) {
            return self.filterMatch(index + 1, content, length, matchString[char]);
        }

        return {isSuccess: true, endIndex: index};
    }
}
